﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using NLog;
using OddUserManager.Model;
using OddUserManager.Service.IServices;
using OddUserManager.Web.Common;
using OddUserManager.Web.Models;

// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace OddUserManager.Web.Controllers
{
    public class JCMatchController : Controller
    {
        static Logger log = LogManager.GetCurrentClassLogger();
        IRealTimeJCMatchService _service;
        IJCTestStrategyGroupService _strategyGroupService;
        private IMemoryCache _memoryCache;

        private int defaultPayOut = 9200;
        public JCMatchController(IRealTimeJCMatchService service, IJCTestStrategyGroupService strategyGroupService, IMemoryCache memoryCache)
        {
            _service = service;
            _strategyGroupService = strategyGroupService;
            _memoryCache = memoryCache;
        }

        public IActionResult GetMatchsByIssue(string issue)
        {
            JsonData d = new JsonData();
            
            try
            {
                if (null == issue || issue == "")
                {
                    return null;
                }
                var matchs = _service.GetMatchsByIssue(issue).OrderBy(p => p.Issue).ThenBy(p => int.Parse(p.MatchNumber.Substring(2))).ToList();
                var cMatchs = ConvertObject(matchs);
                d.Data = cMatchs;

                //d.Data = matchs.OrderBy(p => p.Issue).ThenBy(p => int.Parse(p.MatchNumber.Substring(2))).ToList();
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);

            }
            return Json(d);
        }

        public IActionResult GetNoFinishedMatch()
        {
            JsonData d = new JsonData();
            var matchs = _service.GetNoFinishedMatch().OrderBy(p => p.Issue).ThenBy(p => int.Parse(p.MatchNumber.Substring(2))).ToList();
            var cMatchs = ConvertObject(matchs);
            d.Data = cMatchs;

            return Json(d);
        }


        public IActionResult GetMatchsById(int id)
        {
            JsonData d = new JsonData();
            d.Data = _service.Get(id);
            return Json(d);
        }
        [HttpPost]
        public IActionResult GetMatchsByIds(List<int> ids)
        {
            JsonData d = new JsonData();
            if (ids.Count == 0)
            {
                d.Data = new List<JCMatch>();
                return Json(d);
            }
            d.Data= _service.GetMatchsByIds(ids);
            return Json(d);
        }
        public IActionResult GetAllIssue()
        {
            JsonData d = new JsonData();
            d.Data = _service.GetAllIssues();
            return Json(d);
        }

        public IActionResult GetSingleWeekMatchData(DateTime startTime)
        {
            JsonData d = new JsonData();
            d.Data = _service.GetMatchOptionByTime(startTime, startTime.AddDays(7));
            return Json(d);
        }




        /// <summary>
        /// 转换比赛对象为页面显示对象
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private List<MatchShowModel> ConvertObject(List<JCMatch> list)
        {
            List<MatchShowModel> arrayList = new List<MatchShowModel>();
            var zIndex = 0;
            list.ForEach(match =>
            {
                var brqOdd = match.JCHadOddsList.SingleOrDefault(p => p.FixedOdds == "" && p.ReleaseTime == match.JCHadOddsList.Where(x => x.FixedOdds == "").Max(x => x.ReleaseTime));
                MatchShowModel brqMatch = new MatchShowModel();
                brqMatch.Index = zIndex + 1;
                brqMatch.FiveHundredMatchId = match.FiveHundredMatchId;
                brqMatch.MatchNumber = match.MatchNumber;
                brqMatch.TournamentName = match.TournamentName;
                brqMatch.MatchTime = match.MatchTime.ToString("HH:mm");
                brqMatch.MatchLongTime = match.MatchTime.ToString("yyyy-MM-dd HH:mm:ss");
                brqMatch.HomeTeamId = match.HomeTeamId;
                brqMatch.HomeTeamName = match.HomeTeamName;
                brqMatch.AwayTeamId = match.AwayTeamId;
                brqMatch.AwayTeamName = match.AwayTeamName;
                brqMatch.FiveSeasonId = match.FiveSeasonId;
                brqMatch.WholeScore = match.WholeScore;
                brqMatch.FixedOdds = null == brqOdd ? "" : brqOdd.FixedOdds;
                brqMatch.MatchId = match.MatchId.ToString();
                brqMatch.Issue = match.Issue.ToString();
                brqMatch.CanSingleBet = null == brqOdd ? "0" : brqOdd.CanSingleBet;

                if (null != brqOdd)
                {
                    brqMatch.BOddId = brqOdd.OddId;
                    brqMatch.HomeOdds = ((decimal)brqOdd.HomeOdds).ToString("#0.00");
                    brqMatch.DrawOdds = ((decimal)brqOdd.DrawOdds).ToString("#0.00");
                    brqMatch.AwayOdds = ((decimal)brqOdd.AwayOdds).ToString("#0.00");
                    brqMatch.ReleaseTime = brqOdd.ReleaseTime.ToString("d HH:mm");
                    brqMatch.CurrentPayOut = ((decimal)100m / ((1 / brqOdd.HomeOdds) + (1 / brqOdd.DrawOdds) + (1 / brqOdd.AwayOdds))).ToString("#0.0") + "%";
                }

                MergeCutOdds obj = null != match.CutOddsList ? match.CutOddsList[0] : null;
                if (null != obj)
                {
                    brqMatch.AvgEuropWinOdd = (defaultPayOut / obj.CutWinChance).ToString("#0.00");
                    brqMatch.AvgEuropDrawOdd = (defaultPayOut / obj.CutDrawChance).ToString("#0.00");
                    brqMatch.AvgEuropLoseOdd = (defaultPayOut / obj.CutLoseChance).ToString("#0.00");
                    brqMatch.CutPayOutRate = (obj.CutPayOutRate / 1000000).ToString("#0.0") + "%";
                    brqMatch.BaseDataCount = obj.BaseDataCount;
                    brqMatch.MyCutWinPayOut = obj.MyCutWinChance == 0 ? "" : ((decimal)92 * obj.MyCutWinChance / obj.CutWinChance - 90).ToString("#0.0");
                    brqMatch.MyCutDrawPayOut = obj.MyCutDrawChance == 0 ? "" : ((decimal)92 * obj.MyCutDrawChance / obj.CutDrawChance - 90).ToString("#0.0");
                    brqMatch.MyCutLosePayOut = obj.MyCutLoseChance == 0 ? "" : ((decimal)92 * obj.MyCutLoseChance / obj.CutLoseChance - 90).ToString("#0.0");
                    brqMatch.MyCutWinDeviate = (obj.MyCutWinChance - obj.CutWinChance) == 0 ? "" : ((decimal)(obj.MyCutWinChance - obj.CutWinChance) / 100).ToString("#0.0");
                    brqMatch.MyCutDrawDeviate = (obj.MyCutDrawChance - obj.CutDrawChance) == 0 ? "" : ((decimal)(obj.MyCutDrawChance - obj.CutDrawChance) / 100).ToString("#0.0");
                    brqMatch.MyCutLoseDeviate = (obj.MyCutLoseChance - obj.CutLoseChance) == 0 ? "" : ((decimal)(obj.MyCutLoseChance - obj.CutLoseChance) / 100).ToString("#0.0");
                    brqMatch.MyCutWinChance = obj.MyCutWinChance == 0 ? "" : (obj.MyCutWinChance / 100).ToString("#0.0");
                    brqMatch.MyCutDrawChance = obj.MyCutDrawChance == 0 ? "" : (obj.MyCutDrawChance / 100).ToString("#0.0");
                    brqMatch.MyCutLoseChance = obj.MyCutLoseChance == 0 ? "" : (obj.MyCutLoseChance / 100).ToString("#0.0");
                    if (null != brqOdd)
                    {
                        brqMatch.Deviation = (CalculateDeviation(obj, brqOdd)).ToString("#0.0");
                        brqMatch.JCWinPayOut = brqMatch.MyCutWinChance.Equals("") ? "" : (decimal.Parse(brqMatch.MyCutWinChance) * decimal.Parse(brqMatch.HomeOdds)).ToString("#0.0");
                        brqMatch.JCDrawPayOut = brqMatch.MyCutDrawChance.Equals("") ? "" : (decimal.Parse(brqMatch.MyCutDrawChance) * decimal.Parse(brqMatch.DrawOdds)).ToString("#0.0");
                        brqMatch.JCLosePayOut = brqMatch.MyCutLoseChance.Equals("") ? "" : (decimal.Parse(brqMatch.MyCutLoseChance) * decimal.Parse(brqMatch.AwayOdds)).ToString("#0.0");
                    }
                }

                arrayList.Add(brqMatch);

                var rqOdd = match.JCHadOddsList.SingleOrDefault(p => p.FixedOdds != "" && p.ReleaseTime == match.JCHadOddsList.Where(x => x.FixedOdds != "").Max(x => x.ReleaseTime));
                MatchShowModel rqMatch = new MatchShowModel();
                rqMatch.Index = zIndex + 1;
                rqMatch.FiveHundredMatchId = match.FiveHundredMatchId;
                rqMatch.MatchNumber = match.MatchNumber;
                rqMatch.TournamentName = match.TournamentName;
                rqMatch.MatchTime = match.MatchTime.ToString("HH:mm");
                rqMatch.MatchLongTime = match.MatchTime.ToString("yyyy-MM-dd HH:mm:ss");
                rqMatch.HomeTeamId = match.HomeTeamId;
                rqMatch.HomeTeamName = match.HomeTeamName;
                rqMatch.AwayTeamId = match.AwayTeamId;
                rqMatch.AwayTeamName = match.AwayTeamName;
                rqMatch.FiveSeasonId = match.FiveSeasonId;
                rqMatch.WholeScore = match.WholeScore;
                rqMatch.FixedOdds = null == rqOdd ? "" : rqOdd.FixedOdds;
                rqMatch.MatchId = match.MatchId.ToString();
                rqMatch.Issue = match.Issue.ToString();
                rqMatch.CanSingleBet = null == brqOdd ? "0" : brqOdd.CanSingleBet;
                if (null != rqOdd)
                {
                    rqMatch.BOddId = rqOdd.OddId;
                    rqMatch.HomeOdds = ((decimal)rqOdd.HomeOdds).ToString("#0.00");
                    rqMatch.DrawOdds = ((decimal)rqOdd.DrawOdds).ToString("#0.00");
                    rqMatch.AwayOdds = ((decimal)rqOdd.AwayOdds).ToString("#0.00");
                    rqMatch.ReleaseTime = rqOdd.ReleaseTime.ToString("d HH:mm");
                    rqMatch.CurrentPayOut = ((decimal)100m / ((1 / rqOdd.HomeOdds) + (1 / rqOdd.DrawOdds) + (1 / rqOdd.AwayOdds))).ToString("#0.0") + "%";



                    if (rqOdd.FixedOdds == "-1")
                    {
                        rqMatch.TwoResultPayOut = (100 / (1 / brqOdd.HomeOdds + 1 / rqOdd.AwayOdds)).ToString("#0.0") + "%";
                        //rqMatch.TwoResultPayOut = (100 / (1 / brqOdd.HomeOdds + 1 / rqOdd.AwayOdds)).ToString("#0.0") + "%";
                    }
                    else if (rqOdd.FixedOdds == "+1")
                    {
                        rqMatch.TwoResultPayOut = (100 / (1 / brqOdd.AwayOdds + 1 / rqOdd.HomeOdds)).ToString("#0.0") + "%";
                        //rqMatch.TwoResultPayOut = (100 / (1 / brqOdd.AwayOdds + 1 / rqOdd.HomeOdds)).ToString("#0.0") + "%";
                    }
                }


                if (null != obj)
                {
                    rqMatch.MyCutWinDeviate = obj.MyCutWinChance == 0 ? "" : ((decimal)(obj.MyCutWinChance - obj.CutWinChance) / 100).ToString("#0.0");
                    rqMatch.MyCutDrawDeviate = obj.MyCutDrawChance == 0 ? "" : ((decimal)(obj.MyCutDrawChance - obj.CutDrawChance) / 100).ToString("#0.0");
                    rqMatch.MyCutLoseDeviate = obj.MyCutLoseChance == 0 ? "" : ((decimal)(obj.MyCutLoseChance - obj.CutLoseChance) / 100).ToString("#0.0");

                    //var o = rqJCSectionLists.FirstOrDefault(p => p.SectionNumber == 1);
                    //if (o != null)
                    //{
                    //    currentRow1.Cells[8].Value = o.FixOdds;
                    //}

                    if (obj.MyCutWinChance != 0 && obj.MyCutDrawChance != 0 && obj.MyCutLoseChance != 0 && null != rqOdd)
                    {

                        rqMatch.MyCutWinChance = obj == null ? "" : (GetFixOddsRQChance(rqOdd.FixedOdds, "胜", obj) / 100).ToString("#0.0");
                        rqMatch.MyCutDrawChance = obj == null ? "" : (GetFixOddsRQChance(rqOdd.FixedOdds, "平", obj) / 100).ToString("#0.0");
                        rqMatch.MyCutLoseChance = obj == null ? "" : (GetFixOddsRQChance(rqOdd.FixedOdds, "负", obj) / 100).ToString("#0.0");
                    }

                    rqMatch.JCWinPayOut = rqMatch.MyCutWinChance==null|| rqMatch.MyCutWinChance.Equals("") ? "" : (decimal.Parse(rqMatch.MyCutWinChance) * decimal.Parse(rqMatch.HomeOdds)).ToString("#0.0");
                    rqMatch.JCDrawPayOut = rqMatch.MyCutDrawChance == null || rqMatch.MyCutDrawChance.Equals("") ? "" : (decimal.Parse(rqMatch.MyCutDrawChance) * decimal.Parse(rqMatch.DrawOdds)).ToString("#0.0");
                    rqMatch.JCLosePayOut = rqMatch.MyCutLoseChance == null || rqMatch.MyCutLoseChance.Equals("") ? "" : (decimal.Parse(rqMatch.MyCutLoseChance) * decimal.Parse(rqMatch.AwayOdds)).ToString("#0.0");

                }
                arrayList.Add(rqMatch);
                zIndex++;
            });
            return arrayList;
        }

        private decimal GetFixOddsRQChance(string matchObject, string matchResultSet, MergeCutOdds singleMyCutOdds)
        {
            decimal resultValue = 0;
            if (matchObject.Equals("-4"))
            {
                switch (matchResultSet)
                {
                    case "胜":
                        resultValue = singleMyCutOdds == null ? 0 : singleMyCutOdds.LetNegative4BallsMatchWinChance;
                        break;
                    case "平":
                        resultValue = singleMyCutOdds == null ? 0 : (singleMyCutOdds.LetNegative3BallsMatchWinChance - singleMyCutOdds.LetNegative4BallsMatchWinChance);
                        break;
                    case "负":
                        resultValue = singleMyCutOdds == null ? 0 : (10000 - singleMyCutOdds.LetNegative3BallsMatchWinChance);
                        break;
                }
            }
            else if (matchObject.Equals("-3"))
            {
                switch (matchResultSet)
                {
                    case "胜":
                        resultValue = singleMyCutOdds == null ? 0 : singleMyCutOdds.LetNegative3BallsMatchWinChance;
                        break;
                    case "平":
                        resultValue = singleMyCutOdds == null ? 0 : (singleMyCutOdds.LetNegative2BallsMatchWinChance - singleMyCutOdds.LetNegative3BallsMatchWinChance);
                        break;
                    case "负":
                        resultValue = singleMyCutOdds == null ? 0 : (10000 - singleMyCutOdds.LetNegative2BallsMatchWinChance);
                        break;
                }
            }
            else if (matchObject.Equals("-2"))
            {
                switch (matchResultSet)
                {
                    case "胜":
                        resultValue = singleMyCutOdds == null ? 0 : singleMyCutOdds.LetNegative2BallsMatchWinChance;
                        break;
                    case "平":
                        resultValue = singleMyCutOdds == null ? 0 : (singleMyCutOdds.LetNegative1BallsMatchWinChance - singleMyCutOdds.LetNegative2BallsMatchWinChance);
                        break;
                    case "负":
                        resultValue = singleMyCutOdds == null ? 0 : (10000 - singleMyCutOdds.LetNegative1BallsMatchWinChance);
                        break;
                }
            }
            else if (matchObject.Equals("-1"))
            {
                switch (matchResultSet)
                {
                    case "胜":
                        resultValue = singleMyCutOdds == null ? 0 : singleMyCutOdds.LetNegative1BallsMatchWinChance;
                        break;
                    case "平":
                        resultValue = singleMyCutOdds == null ? 0 : (singleMyCutOdds.MyCutWinChance - singleMyCutOdds.LetNegative1BallsMatchWinChance);
                        break;
                    case "负":
                        resultValue = singleMyCutOdds == null ? 0 : (10000 - singleMyCutOdds.MyCutWinChance);
                        break;
                }
            }
            else if (matchObject.Equals("+1"))
            {
                switch (matchResultSet)
                {
                    case "胜":
                        resultValue = singleMyCutOdds == null ? 0 : (10000 - singleMyCutOdds.MyCutLoseChance);
                        break;
                    case "平":
                        resultValue = singleMyCutOdds == null ? 0 : (singleMyCutOdds.MyCutLoseChance - singleMyCutOdds.Let1BallsMatchWinChance);
                        break;
                    case "负":
                        resultValue = singleMyCutOdds == null ? 0 : singleMyCutOdds.Let1BallsMatchWinChance;
                        break;
                }
            }
            else if (matchObject.Equals("+2"))
            {
                switch (matchResultSet)
                {
                    case "胜":
                        resultValue = singleMyCutOdds == null ? 0 : (10000 - singleMyCutOdds.Let1BallsMatchWinChance);
                        break;
                    case "平":
                        resultValue = singleMyCutOdds == null ? 0 : (singleMyCutOdds.Let1BallsMatchWinChance - singleMyCutOdds.Let2BallsMatchWinChance);
                        break;
                    case "负":
                        resultValue = singleMyCutOdds == null ? 0 : singleMyCutOdds.Let2BallsMatchWinChance;
                        break;
                }
            }
            else if (matchObject.Equals("+3"))
            {
                switch (matchResultSet)
                {
                    case "胜":
                        resultValue = singleMyCutOdds == null ? 0 : (10000 - singleMyCutOdds.Let2BallsMatchWinChance);
                        break;
                    case "平":
                        resultValue = singleMyCutOdds == null ? 0 : (singleMyCutOdds.Let2BallsMatchWinChance - singleMyCutOdds.Let3BallsMatchWinChance);
                        break;
                    case "负":
                        resultValue = singleMyCutOdds == null ? 0 : singleMyCutOdds.Let3BallsMatchWinChance;
                        break;
                }
            }
            return resultValue;
        }
        public decimal CalculateDeviation(MergeCutOdds obj, JCHadOdds sec)
        {
            if (null == obj || null == sec) { return 0; }
            else
            {
                var num1 = Math.Abs(obj.MyCutWinChance * sec.HomeOdds / 100 - defaultPayOut * obj.MyCutWinChance / obj.CutWinChance / 100);
                var num2 = Math.Abs(obj.MyCutDrawChance * sec.DrawOdds / 100 - defaultPayOut * obj.MyCutDrawChance / obj.CutDrawChance / 100);
                var num3 = Math.Abs(obj.MyCutLoseChance * sec.AwayOdds / 100 - defaultPayOut * obj.MyCutLoseChance / obj.CutLoseChance / 100);
                return num1 + num2 + num3;
            }
        }

        public IActionResult GetSelectedMatchResults(string issue,List<int> groupIds)
        {
            JsonData result = new JsonData();
            try
            {
                List<JCLotteryBillSelectedMatchsTest> list = null;
                List<JCMatch> matchList = null;
                if (null == issue || issue == "")
                {
                    matchList = _service.GetNoFinishedMatch();
                }
                else
                {
                    matchList = _service.GetMatchsByIssue(issue);
                }
               
                if (groupIds.Count > 0)
                {
                    List<JCTestStrategyGroup> groupList = new List<JCTestStrategyGroup>();
                    for (var i = 0; i < groupIds.Count; i++)
                    {
                        var group = _strategyGroupService.GetJCTestStrategyGroupById(groupIds[i]);
                        groupList.Add(group);
                    }

                    list = JCMatchUtils.GetSelectedMatchResults(matchList, groupList);
                    result.Success = true;
                    result.Message = "";
                    result.Data = list;

                }
                else
                {
                    result.Success = false;
                    result.Message = "没有设置选择的策略组";
                    result.Data = null;
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
                result.Success = false;
                result.Message = ex.Message;
                result.Data = null;
            }
            return Json(result);
        }


        public async Task<IActionResult> GetNewMatchNumbers()
        {
            JsonData d = new JsonData();
            try
            {
                var result = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
                var appUserId = 0;
                if (result.Succeeded)
                {
                    appUserId = int.Parse(result.Principal.Identity.Name);
                }
                else
                {
                    throw new Exception("用户凭证失效");
                }

                var matchs = _service.GetNoFinishedMatch();
                string time = "";
                string cacheKey = appUserId.ToString();
                
                if (_memoryCache.TryGetValue(cacheKey, out time))
                {
                    var cm = matchs.Where(p => p.MatchTime > DateTime.Parse(time));
                    if (cm.Count() > 0)
                    {
                        time = matchs.Max(p=>p.MatchTime).ToString();
                        _memoryCache.Set(cacheKey, time);
                        d.Data = cm.Select(p => p.MatchNumber).ToList();
                    }
                }
                else {
                    time = matchs.Max(p => p.MatchTime).ToString();

                    _memoryCache.Set(cacheKey, time);
                }
            }
            catch (Exception ex)
            {
                d.Success = false;
                d.Message = ex.Message;
            }
            return Json(d);
        }


    }
}
